package com.expert.miniapp.service.impl;

import com.expert.miniapp.dao.Demand;
import com.expert.miniapp.dao.DemandMapper;
import com.expert.miniapp.dao.Recommendation;
import com.expert.miniapp.dao.RecommendationItem;
import com.expert.miniapp.dao.RecommendationItemMapper;
import com.expert.miniapp.dao.RecommendationMapper;
import com.expert.miniapp.dto.AIMatchResult;
import com.expert.miniapp.dto.DemandDTO;
import com.expert.miniapp.dto.DemandHistoryDTO;
import com.expert.miniapp.dto.RecommendationResponseDTO;
import com.expert.miniapp.service.DemandService;
import com.expert.miniapp.service.AIDemandSummaryService;
import com.expert.miniapp.util.DifyClient;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.expert.miniapp.config.AIMatchingConfigProperties;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * DemandServiceImpl - 需求服务实现类
 *
 * @author System
 * @since 2025-10-19
 */
@Service
public class DemandServiceImpl implements DemandService {

    private static final Logger logger = LoggerFactory.getLogger(DemandServiceImpl.class);

    @Autowired
    private DemandMapper demandMapper;

    @Autowired
    private RecommendationMapper recommendationMapper;

    @Autowired
    private RecommendationItemMapper recommendationItemMapper;

    @Autowired
    private AIMatchingConfigProperties aiConfig;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private AIDemandSummaryService aiDemandSummaryService;

    /**
     * 创建新需求（状态默认为DRAFT）
     *
     * @param demandDTO 需求DTO对象
     * @return 创建后的需求对象
     */
    @Override
    @Transactional
    public Demand createDemand(DemandDTO demandDTO) {
        logger.info("创建新需求: userId={}", demandDTO.getUserId());

        try {
            // 创建Demand实体
            Demand demand = new Demand();

            // 生成UUID作为需求ID
            demand.setDemandId(UUID.randomUUID().toString());
            demand.setUserId(demandDTO.getUserId());
            demand.setDemandStatus("DRAFT");  // 默认状态为草稿
            demand.setCreatedAt(LocalDateTime.now());

            // 设置所有字段
            copyDtoToEntity(demandDTO, demand);

            // 插入数据库
            int rows = demandMapper.insertDemand(demand);

            if (rows > 0) {
                logger.info("需求创建成功: demandId={}", demand.getDemandId());
                return demand;
            } else {
                logger.error("需求创建失败: 插入数据库返回0行");
                throw new RuntimeException("需求创建失败");
            }

        } catch (Exception e) {
            logger.error("创建需求失败", e);
            throw new RuntimeException("创建需求失败：" + e.getMessage(), e);
        }
    }

    /**
     * 运行AI智能匹配并持久化推荐与明细。
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RecommendationResponseDTO runAIMatchAndPersist(String demandId) {
        logger.info("Run AI matching for demandId={}", demandId);

        // 1) 校验需求存在
        Demand demand = demandMapper.selectByPrimaryKey(demandId);
        if (demand == null) {
            throw new IllegalArgumentException("需求不存在: " + demandId);
        }

        // 2) 构建Dify inputs（包含所有需求字段，数组字段解析为实际数组）
        Map<String, Object> inputs = buildDemandInputs(demand);

        logger.info("AI匹配请求 (Dify) - demandId: {}, inputs字段数: {}", demandId, inputs.size());
        try {
            logger.debug("Dify inputs内容: {}", objectMapper.writeValueAsString(inputs));
        } catch (Exception e) {
            logger.warn("无法序列化inputs用于日志: {}", e.getMessage());
        }

        // 3) 调用OpenAI格式API（/chat/completions端点）
        String content;
        try {
            logger.info("=== 开始调用AI匹配接口（OpenAI格式） ===");
            logger.info("URL: {}", aiConfig.getUrl());
            logger.info("Model: {}", aiConfig.getModel());

            long startTime = System.currentTimeMillis();
            content = DifyClient.callOpenAIFormat(
                    aiConfig.getUrl(),
                    aiConfig.getKey(),
                    inputs,                  // 作为message.content对象
                    aiConfig.getModel(),     // gpt-4o-mini
                    false,                   // stream=false（非流式）
                    aiConfig.getTimeout()
            );
            long elapsed = System.currentTimeMillis() - startTime;

            logger.info("=== AI响应成功 ===");
            logger.info("响应时间: {} 毫秒", elapsed);
            logger.info("返回内容长度: {} 字符", content.length());
            logger.debug("返回内容前200字符: {}", content.length() > 0 ?
                    content.substring(0, Math.min(200, content.length())) : "空内容");

        } catch (Exception e) {
            logger.error("AI匹配调用失败: {}", e.getMessage(), e);
            throw new RuntimeException("AI匹配失败: " + e.getMessage(), e);
        }

        // 验证content不为空
        if (!StringUtils.hasText(content)) {
            throw new RuntimeException("AI返回的内容为空");
        }
// 4) 解析为匹配结果列表
        List<AIMatchResult> results;
        try {
            String normalized = normalizeToJsonArray(content);
            results = objectMapper.readValue(normalized, new TypeReference<List<AIMatchResult>>(){});
        } catch (Exception e) {
            throw new RuntimeException("匹配结果解析失败: " + e.getMessage(), e);
        }
        if (results == null || results.isEmpty()) {
            throw new RuntimeException("匹配结果为空");
        }

        // 5) 统计各类型数量并持久化推荐与明细
        String recommendationId = UUID.randomUUID().toString();
        Recommendation rec = new Recommendation();
        rec.setRecommendationId(recommendationId);
        rec.setDemandId(demandId);

        int expert = 0, achievement = 0, instrument = 0, laboratory = 0, other = 0;
        List<RecommendationItem> items = new ArrayList<>();
        int rank = 1;
        for (AIMatchResult r : results) {
            String type = resolveResourceTypeById(r.getResourceId());
            switch (type) {
                case "科研专家" -> expert++;
                case "科技成果" -> achievement++;
                case "仪器设备" -> instrument++;
                case "实验基地" -> laboratory++;
                default -> other++;
            }
            RecommendationItem item = new RecommendationItem();
            item.setItemId(UUID.randomUUID().toString());
            item.setRecommendationId(recommendationId);
            item.setRankOrder(rank++);
            item.setResourceType(type);
            item.setResourceId(r.getResourceId());
            item.setScore(parseRateToScore(r.getMatchRate()));
            item.setReason(r.getMatchReason());
            item.setAnalysisReport(null);
            item.setIsAddedToCase(false);
            item.setIsAddedToResource(false);
            item.setCreatedAt(LocalDateTime.now());
            items.add(item);
        }

        rec.setMatchedExpertCount(expert);
        rec.setMatchedAchievementCount(achievement);
        rec.setMatchedInstrumentCount(instrument);
        rec.setMatchedLaboratoryCount(laboratory);
        rec.setMatchedOtherCount(other);
        rec.setTotalCount(items.size());
        rec.setCreatedAt(LocalDateTime.now());

        recommendationMapper.insert(rec);
        recommendationItemMapper.insertBatch(items);

        // 6) 构造返回DTO
        RecommendationResponseDTO dto = new RecommendationResponseDTO();
        dto.setRecommendationId(recommendationId);
        dto.setDemandId(demandId);
        dto.setTotalCount(items.size());
        dto.setItems(items);
        dto.setCreatedAt(rec.getCreatedAt());
        RecommendationResponseDTO.ResourceStatistics stats = new RecommendationResponseDTO.ResourceStatistics(
                expert, achievement, instrument, laboratory, other
        );
        dto.setStatistics(stats);
        return dto;
    }

    private String resolveResourceTypeById(String resourceId) {
        if (resourceId == null) return "其他资源";
        if (resourceId.startsWith("KYZJ")) return "科研专家";
        if (resourceId.startsWith("KJCG")) return "科技成果";
        if (resourceId.startsWith("YQSB")) return "仪器设备";
        if (resourceId.startsWith("SYJD")) return "实验基地";
        if (resourceId.startsWith("QTZY")) return "其他资源";
        return "其他资源";
    }

    private java.math.BigDecimal parseRateToScore(String rate) {
        try {
            if (rate == null) return java.math.BigDecimal.ZERO;
            String digits = rate.replace("%", "").trim();
            return new java.math.BigDecimal(digits);
        } catch (Exception e) {
            return java.math.BigDecimal.ZERO;
        }
    }

    private String normalizeToJsonArray(String text) {
        String t = text.trim();
        // 尝试提取第一个 '[' 到最后一个 ']' 的子串
        int start = t.indexOf('[');
        int end = t.lastIndexOf(']');
        if (start >= 0 && end > start) {
            t = t.substring(start, end + 1);
        }
        // 将单引号替换为双引号，降低解析失败概率
        t = t.replace('\'', '"');
        return t;
    }

    /**
     * 更新需求信息
     *
     * @param demandId  需求ID
     * @param demandDTO 需求DTO对象
     * @return 更新后的需求对象
     */
    @Override
    @Transactional
    public Demand updateDemand(String demandId, DemandDTO demandDTO) {
        logger.info("更新需求: demandId={}", demandId);

        try {
            // 查询现有需求
            Demand existingDemand = demandMapper.selectByPrimaryKey(demandId);
            if (existingDemand == null) {
                logger.warn("需求不存在: demandId={}", demandId);
                throw new RuntimeException("需求不存在");
            }

            // 只有DRAFT状态的需求才能更新
            if (!"DRAFT".equals(existingDemand.getDemandStatus())) {
                logger.warn("只有草稿状态的需求才能更新: demandId={}, status={}", demandId, existingDemand.getDemandStatus());
                throw new RuntimeException("只有草稿状态的需求才能更新");
            }

            // 更新字段
            existingDemand.setDemandId(demandId);
            copyDtoToEntity(demandDTO, existingDemand);

            // 更新数据库
            int rows = demandMapper.updateDemand(existingDemand);

            if (rows > 0) {
                logger.info("需求更新成功: demandId={}", demandId);
                return demandMapper.selectByPrimaryKey(demandId);
            } else {
                logger.error("需求更新失败: 更新数据库返回0行");
                throw new RuntimeException("需求更新失败");
            }

        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            logger.error("更新需求失败: demandId={}", demandId, e);
            throw new RuntimeException("更新需求失败：" + e.getMessage(), e);
        }
    }

    /**
     * 提交需求（状态从DRAFT变更为SUBMITTED）
     *
     * @param demandId 需求ID
     * @return 提交后的需求对象
     */
    @Override
    @Transactional
    public Demand submitDemand(String demandId) {
        logger.info("提交需求: demandId={}", demandId);

        try {
            // 1. 查询现有需求
            Demand existingDemand = demandMapper.selectByPrimaryKey(demandId);
            if (existingDemand == null) {
                logger.warn("需求不存在: demandId={}", demandId);
                throw new RuntimeException("需求不存在");
            }

            // 2. 只有DRAFT状态的需求才能提交
            if (!"DRAFT".equals(existingDemand.getDemandStatus())) {
                logger.warn("只有草稿状态的需求才能提交: demandId={}, status={}", demandId, existingDemand.getDemandStatus());
                throw new RuntimeException("只有草稿状态的需求才能提交");
            }

            // 3. 生成AI摘要（新增逻辑）
            logger.info("开始生成AI摘要: demandId={}", demandId);
            try {
                String summary = aiDemandSummaryService.generateDemandSummary(existingDemand);

                if (summary == null || summary.trim().isEmpty()) {
                    throw new RuntimeException("AI返回的摘要为空");
                }

                existingDemand.setSummary(summary);
                demandMapper.updateDemand(existingDemand);

                logger.info("AI摘要生成成功: demandId={}, 摘要长度={}", demandId, summary.length());

            } catch (Exception e) {
                logger.error("AI摘要生成失败: demandId={}", demandId, e);
                // 根据计划：阻止提交
                throw new RuntimeException("生成AI摘要失败，无法提交需求: " + e.getMessage(), e);
            }

            // 4. 更新状态为SUBMITTED，并设置提交时间
            int rows = demandMapper.updateDemandStatus(demandId, "SUBMITTED");

            if (rows > 0) {
                logger.info("需求提交成功: demandId={}", demandId);
                return demandMapper.selectByPrimaryKey(demandId);
            } else {
                logger.error("需求提交失败: 更新状态返回0行");
                throw new RuntimeException("需求提交失败");
            }

        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            logger.error("提交需求失败: demandId={}", demandId, e);
            throw new RuntimeException("提交需求失败：" + e.getMessage(), e);
        }
    }

    /**
     * 根据需求ID获取需求详情
     *
     * @param demandId 需求ID
     * @return 需求对象，如果不存在则返回null
     */
    @Override
    public Demand getDemandById(String demandId) {
        logger.info("查询需求详情: demandId={}", demandId);

        try {
            Demand demand = demandMapper.selectByPrimaryKey(demandId);

            if (demand == null) {
                logger.warn("需求不存在: demandId={}", demandId);
            } else {
                logger.info("查询需求详情成功: demandId={}", demandId);
            }

            return demand;

        } catch (Exception e) {
            logger.error("查询需求详情失败: demandId={}", demandId, e);
            throw new RuntimeException("查询需求详情失败：" + e.getMessage(), e);
        }
    }

    /**
     * 根据用户ID获取需求列表
     *
     * @param userId 用户ID
     * @return 需求列表
     */
    @Override
    public PageInfo<Demand> getDemandsByUserId(String userId, int pageNum, int pageSize) {
        logger.info("Fetching demand list: userId={}, pageNum={}, pageSize={}", userId, pageNum, pageSize);

        try {
            PageHelper.startPage(pageNum, pageSize);
            List<Demand> demands = demandMapper.selectByUserId(userId);
            PageInfo<Demand> pageInfo = new PageInfo<>(demands);
            logger.info("Demand list query succeeded: currentSize={}, totalPages={}", pageInfo.getList().size(), pageInfo.getPages());
            return pageInfo;

        } catch (Exception e) {
            logger.error("Failed to query user demand list: userId={}", userId, e);
            throw new RuntimeException("查询用户需求列表失败:" + e.getMessage(), e);
        }
    }

    /**
     * 获取所有需求列表
     *
     * @return 需求列表
     */
    @Override
    public List<Demand> getAllDemands() {
        logger.info("查询所有需求");

        try {
            List<Demand> demands = demandMapper.selectAll();
            logger.info("查询成功，共查询到 {} 条需求记录", demands.size());
            return demands;

        } catch (Exception e) {
            logger.error("查询所有需求失败", e);
            throw new RuntimeException("查询所有需求失败：" + e.getMessage(), e);
        }
    }

    /**
     * 删除需求（级联删除所有推荐记录）
     *
     * @param demandId 需求ID
     * @return 删除结果信息（删除的记录数）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Integer> deleteByIdCascade(String demandId) {
        logger.info("级联删除需求: demandId={}", demandId);

        Map<String, Integer> result = new HashMap<>();

        try {
            // 1. 查询需求是否存在
            Demand demand = demandMapper.selectByPrimaryKey(demandId);
            if (demand == null) {
                logger.warn("需求不存在: demandId={}", demandId);
                throw new IllegalArgumentException("需求不存在: " + demandId);
            }

            // 2. 查询该需求的所有推荐记录
            List<Recommendation> recommendations = recommendationMapper.findByDemandId(demandId);
            logger.info("找到 {} 条推荐记录", recommendations.size());

            int totalItemsDeleted = 0;

            // 3. 删除每个推荐记录的明细
            for (Recommendation rec : recommendations) {
                int itemsDeleted = recommendationItemMapper.deleteByRecommendationId(rec.getRecommendationId());
                totalItemsDeleted += itemsDeleted;
                logger.debug("删除推荐明细: recommendationId={}, 删除 {} 条", rec.getRecommendationId(), itemsDeleted);
            }

            // 4. 删除所有推荐记录
            int recommendationsDeleted = recommendationMapper.deleteByDemandId(demandId);
            logger.info("删除推荐记录: {} 条", recommendationsDeleted);

            // 5. 删除需求本身
            int demandDeleted = demandMapper.deleteByPrimaryKey(demandId);
            logger.info("删除需求: {} 条", demandDeleted);

            // 6. 构建返回结果
            result.put("demandDeleted", demandDeleted);
            result.put("recommendationsDeleted", recommendationsDeleted);
            result.put("itemsDeleted", totalItemsDeleted);

            logger.info("级联删除成功: 需求={}, 推荐={}, 明细={}", demandDeleted, recommendationsDeleted, totalItemsDeleted);

            return result;

        } catch (IllegalArgumentException e) {
            throw e;
        } catch (Exception e) {
            logger.error("级联删除需求失败: demandId={}", demandId, e);
            throw new RuntimeException("级联删除需求失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取用户需求历史记录列表（带分页和时间筛选）
     *
     * @param userId    用户ID
     * @param pageNum   页码
     * @param pageSize  每页大小
     * @param startTime 开始时间（可选）
     * @param endTime   结束时间（可选）
     * @return 分页结果
     */
    @Override
    public PageInfo<DemandHistoryDTO> getUserDemandsWithPagination(
            String userId,
            Integer pageNum,
            Integer pageSize,
            LocalDateTime startTime,
            LocalDateTime endTime
    ) {
        logger.info("查询用户需求历史: userId={}, pageNum={}, pageSize={}, startTime={}, endTime={}",
                userId, pageNum, pageSize, startTime, endTime);

        try {
            // 1. 设置分页参数
            PageHelper.startPage(pageNum, pageSize);

            // 2. 查询用户的所有需求
            List<Demand> demands = demandMapper.selectByUserId(userId);

            // 3. 时间筛选（如果提供了时间范围）
            if (startTime != null || endTime != null) {
                demands = demands.stream()
                        .filter(demand -> {
                            LocalDateTime createdAt = demand.getCreatedAt();
                            if (createdAt == null) return false;

                            if (startTime != null && createdAt.isBefore(startTime)) {
                                return false;
                            }
                            if (endTime != null && createdAt.isAfter(endTime)) {
                                return false;
                            }
                            return true;
                        })
                        .collect(Collectors.toList());
            }

            // 4. 转换为DemandHistoryDTO
            List<DemandHistoryDTO> historyList = new ArrayList<>();

            for (Demand demand : demands) {
                DemandHistoryDTO dto = new DemandHistoryDTO();

                // 设置需求基本信息
                dto.setDemandId(demand.getDemandId());
                dto.setUserId(demand.getUserId());
                dto.setDemandStatus(demand.getDemandStatus());
                dto.setResearchObjective(demand.getResearchObjective());
                dto.setTechnologyField(demand.getTechnologyField());
                dto.setCreatedAt(demand.getCreatedAt());
                dto.setSubmittedAt(demand.getSubmittedAt());

                // 查询推荐记录数量
                int recommendationCount = recommendationMapper.countByDemandId(demand.getDemandId());
                dto.setRecommendationCount(recommendationCount);

                // 查询最新的推荐记录
                Recommendation lastRecommendation = recommendationMapper.findLatestByDemandId(demand.getDemandId());

                if (lastRecommendation != null) {
                    DemandHistoryDTO.LastRecommendation lastRecDTO = new DemandHistoryDTO.LastRecommendation();
                    lastRecDTO.setRecommendationId(lastRecommendation.getRecommendationId());
                    lastRecDTO.setTotalCount(lastRecommendation.getTotalCount());
                    lastRecDTO.setMatchedExpertCount(lastRecommendation.getMatchedExpertCount());
                    lastRecDTO.setMatchedAchievementCount(lastRecommendation.getMatchedAchievementCount());
                    lastRecDTO.setMatchedInstrumentCount(lastRecommendation.getMatchedInstrumentCount());
                    lastRecDTO.setMatchedLaboratoryCount(lastRecommendation.getMatchedLaboratoryCount());
                    lastRecDTO.setMatchedOtherCount(lastRecommendation.getMatchedOtherCount());
                    lastRecDTO.setCreatedAt(lastRecommendation.getCreatedAt());

                    dto.setLastRecommendation(lastRecDTO);
                }

                historyList.add(dto);
            }

            // 5. 构建分页结果
            PageInfo<DemandHistoryDTO> pageInfo = new PageInfo<>(historyList);

            logger.info("查询成功，共 {} 条记录，当前页 {} 条", pageInfo.getTotal(), historyList.size());

            return pageInfo;

        } catch (Exception e) {
            logger.error("查询用户需求历史失败: userId={}", userId, e);
            throw new RuntimeException("查询用户需求历史失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取需求完整详情（包含需求信息和推荐记录）
     *
     * @param demandId 需求ID
     * @return 完整详情Map（demand + recommendations）
     */
    @Override
    public Map<String, Object> getDemandComplete(String demandId) {
        logger.info("查询需求完整详情: demandId={}", demandId);

        try {
            // 1. 查询需求基本信息
            Demand demand = demandMapper.selectByPrimaryKey(demandId);
            if (demand == null) {
                logger.warn("需求不存在: demandId={}", demandId);
                throw new IllegalArgumentException("需求不存在: " + demandId);
            }

            // 2. 查询所有推荐记录
            List<Recommendation> recommendations = recommendationMapper.findByDemandId(demandId);

            // 3. 为每个推荐记录查询明细
            List<Map<String, Object>> recommendationsWithItems = new ArrayList<>();

            for (Recommendation rec : recommendations) {
                Map<String, Object> recData = new HashMap<>();
                recData.put("recommendation", rec);

                // 查询推荐明细
                List<RecommendationItem> items = recommendationItemMapper.findByRecommendationId(rec.getRecommendationId());
                recData.put("items", items);

                recommendationsWithItems.add(recData);
            }

            // 4. 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("demand", demand);
            result.put("recommendations", recommendationsWithItems);

            logger.info("查询成功，需求包含 {} 个推荐记录", recommendations.size());

            return result;

        } catch (IllegalArgumentException e) {
            throw e;
        } catch (Exception e) {
            logger.error("查询需求完整详情失败: demandId={}", demandId, e);
            throw new RuntimeException("查询需求完整详情失败: " + e.getMessage(), e);
        }
    }

    /**
     * 将DTO对象的数据复制到Entity对象
     *
     * @param dto    源DTO对象
     * @param entity 目标Entity对象
     */
    private String buildDemandContentJson(Demand demand) {
        // 严格按测试报告的字段与命名进行映射，仅上传核心字段
        Map<String, Object> m = new LinkedHashMap<>();
        m.put("demand_name", safe(demand.getDemandName()));
        m.put("demand_id", safe(demand.getDemandId()));
        m.put("user_id", safe(demand.getUserId()));
        m.put("research_objective", safe(demand.getResearchObjective()));
        m.put("core_technical_challenges", safe(demand.getCoreTechnicalChallenges()));
        m.put("technology_field", safe(demand.getTechnologyField()));
        m.put("application_scenario", safe(demand.getApplicationScenario()));
        m.put("expected_outcomes", safe(demand.getExpectedOutcomes()));
        m.put("resource_type_selection", safe(demand.getResourceTypeSelection()));
        m.put("expert_type", safe(demand.getExpertType()));
        m.put("cooperation_form", safe(demand.getCooperationForm()));
        m.put("budget_range", safe(demand.getBudgetRange()));
        m.put("timeline_requirement", safe(demand.getTimelineRequirement()));

        try {
            return objectMapper.writeValueAsString(m);
        } catch (Exception e) {
            throw new RuntimeException("需求JSON序列化失败: " + e.getMessage(), e);
        }
    }

    private String safe(Object v) {
        if (v == null) return "None";
        String s = v.toString().trim();
        return s.isEmpty() ? "None" : s;
    }

    private void copyDtoToEntity(DemandDTO dto, Demand entity) {
        entity.setResearchObjective(dto.getResearchObjective());
        entity.setCoreTechnicalChallenges(dto.getCoreTechnicalChallenges());
        entity.setApplicationScenario(dto.getApplicationScenario());
        entity.setExpectedOutcomes(dto.getExpectedOutcomes());
        entity.setCurrentTechnologyStatus(dto.getCurrentTechnologyStatus());
        entity.setTechnologyField(dto.getTechnologyField());
        entity.setCurrentResearchStage(dto.getCurrentResearchStage());
        entity.setDocumentUpload(dto.getDocumentUpload());
        entity.setResourceTypeSelection(dto.getResourceTypeSelection());
        entity.setExpertType(dto.getExpertType());
        entity.setExpertRequirements(dto.getExpertRequirements());
        entity.setAchievementType(dto.getAchievementType());
        entity.setTechnologyMaturity(dto.getTechnologyMaturity());
        entity.setLaboratoryType(dto.getLaboratoryType());
        entity.setAreaRequirement(dto.getAreaRequirement());
        entity.setEquipmentType(dto.getEquipmentType());
        entity.setUsageDuration(dto.getUsageDuration());
        entity.setOtherResources(dto.getOtherResources());
        entity.setCooperationForm(dto.getCooperationForm());
        entity.setBudgetRange(dto.getBudgetRange());
        entity.setTimelineRequirement(dto.getTimelineRequirement());
        entity.setRegionalRequirement(dto.getRegionalRequirement());
        entity.setIntellectualProperty(dto.getIntellectualProperty());
        entity.setUrgencyLevel(dto.getUrgencyLevel());
        entity.setExpectedContactTime(dto.getExpectedContactTime());
        entity.setConfidentialityRequirement(dto.getConfidentialityRequirement());
    }

    /**
     * 重新生成需求的AI摘要
     *
     * @param demandId 需求ID
     * @return 更新后的需求对象
     */
    @Override
    @Transactional
    public Demand regenerateDemandSummary(String demandId) {
        logger.info("重新生成需求摘要: demandId={}", demandId);

        try {
            // 1. 查询需求
            Demand demand = demandMapper.selectByPrimaryKey(demandId);
            if (demand == null) {
                logger.warn("需求不存在: demandId={}", demandId);
                throw new IllegalArgumentException("需求不存在: " + demandId);
            }

            // 2. 生成AI摘要
            logger.info("调用AI生成摘要: demandId={}", demandId);
            String summary = aiDemandSummaryService.generateDemandSummary(demand);

            if (summary == null || summary.trim().isEmpty()) {
                throw new RuntimeException("AI返回的摘要为空");
            }

            // 3. 更新摘要
            demand.setSummary(summary);
            int rows = demandMapper.updateDemand(demand);

            if (rows > 0) {
                logger.info("摘要重新生成成功: demandId={}, 摘要长度={}", demandId, summary.length());
                return demandMapper.selectByPrimaryKey(demandId);
            } else {
                throw new RuntimeException("更新摘要失败");
            }

        } catch (IllegalArgumentException e) {
            throw e;
        } catch (Exception e) {
            logger.error("重新生成摘要失败: demandId={}", demandId, e);
            throw new RuntimeException("重新生成摘要失败: " + e.getMessage(), e);
        }
    }

    /**
     * 构建Dify inputs对象（Dify API格式）
     * 将Demand实体的字段转换为inputs Map，数组字段解析为实际数组
     *
     * @param demand 需求实体
     * @return Dify inputs对象
     */
    private Map<String, Object> buildDemandInputs(Demand demand) {
        Map<String, Object> inputs = new LinkedHashMap<>();

        // 简单字符串字段
        inputs.put("demand_name", safe(demand.getDemandName()));
        inputs.put("demand_id", safe(demand.getDemandId()));
        inputs.put("user_id", safe(demand.getUserId()));
        inputs.put("research_objective", safe(demand.getResearchObjective()));
        inputs.put("core_technical_challenges", safe(demand.getCoreTechnicalChallenges()));
        inputs.put("application_scenario", safe(demand.getApplicationScenario()));
        inputs.put("current_technology_status", safe(demand.getCurrentTechnologyStatus()));
        inputs.put("current_research_stage", safe(demand.getCurrentResearchStage()));
        inputs.put("budget_range", safe(demand.getBudgetRange()));
        inputs.put("timeline_requirement", safe(demand.getTimelineRequirement()));
        inputs.put("urgency_level", safe(demand.getUrgencyLevel()));
        inputs.put("expected_contact_time", safe(demand.getExpectedContactTime()));
        inputs.put("confidentiality_requirement", safe(demand.getConfidentialityRequirement()));
        inputs.put("intellectual_property", safe(demand.getIntellectualProperty()));
        inputs.put("usage_duration", safe(demand.getUsageDuration()));
        inputs.put("technology_maturity", safe(demand.getTechnologyMaturity()));

        // 数组字段 - 尝试解析为数组，失败则作为字符串
        inputs.put("technology_field", parseArrayField(demand.getTechnologyField()));
        inputs.put("expected_outcomes", parseArrayField(demand.getExpectedOutcomes()));
        inputs.put("resource_type_selection", parseArrayField(demand.getResourceTypeSelection()));
        inputs.put("expert_type", parseArrayField(demand.getExpertType()));
        inputs.put("expert_requirements", parseArrayField(demand.getExpertRequirements()));
        inputs.put("cooperation_form", parseArrayField(demand.getCooperationForm()));
        inputs.put("regional_requirement", parseArrayField(demand.getRegionalRequirement()));
        inputs.put("laboratory_type", parseArrayField(demand.getLaboratoryType()));
        inputs.put("area_requirement", parseArrayField(demand.getAreaRequirement()));
        inputs.put("equipment_type", parseArrayField(demand.getEquipmentType()));
        inputs.put("achievement_type", parseArrayField(demand.getAchievementType()));

        return inputs;
    }

    /**
     * 解析数组字段
     * 如果是JSON数组格式字符串则解析为List，否则返回原字符串
     *
     * @param fieldValue 字段值
     * @return 数组或字符串
     */
    private Object parseArrayField(Object fieldValue) {
        if (fieldValue == null) {
            return "None";
        }

        String str = fieldValue.toString().trim();
        if (str.isEmpty()) {
            return "None";
        }

        // 尝试解析为JSON数组
        if (str.startsWith("[") && str.endsWith("]")) {
            try {
                return objectMapper.readValue(str, List.class);
            } catch (Exception e) {
                logger.warn("无法解析数组字段，作为字符串处理: {}", str);
                return str;
            }
        }

        return str;
    }

}

